home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / jazlib.arc / WPRINTF.C < prev    next >
Text File  |  1988-12-18  |  6KB  |  291 lines

  1. /*
  2.  *    KPRINTF -- "kernel" formatted print routines for DeSmet C
  3.  *
  4.  *    Copyright 1985 by John McNamee.
  5.  *    This software may be freely copied for non-commercial use.
  6.  *    Commercial use requires the written permission of the author.
  7.  *
  8.  *        John McNamee
  9.  *        7560 McLaren Ave.
  10.  *        Canoga Park, CA 91307
  11.  *
  12.  *        CompuServe: 70235,1345
  13.  *        Usenet: decvax!philabs!sbcs!bnl!jpm
  14.  *        Internet: jpm@BNL.ARPA
  15.  */
  16.  
  17. /*
  18.  *            Overview of this package:
  19.  *
  20.  * kprintf() and ksprintf() should act exactly like printf and sprintf, except
  21.  * they don't do floating point. The idea is to avoid bringing in the floating
  22.  * point and file handling library routines that get loaded every time the
  23.  * normal printf or sprintf are called. My routines add less than 2K to
  24.  * program size, while normal printf adds over 6K. Of course, if you are going
  25.  * to do file I/O or floating point you mind as well use the normal routines.
  26.  * These functions are for writing programs programs that wouldn't otherwise
  27.  * bring in all that code.
  28.  *
  29.  * I'm sure this code could be made smaller and faster. This was done "quick
  30.  * and dirty" and I don't want to hear from anybody about bad coding style.
  31.  * This really should be written in assembly language, but who has the time?
  32.  */
  33.  
  34. /*
  35.  *    Notes on converting to something other than DeSmet C:
  36.  *
  37.  * It shouldn't be too hard to move these routines to another C compiler.
  38.  * The main thing you will have to do is check if calling putchar() brings
  39.  * in the whole file I/O library of your compiler. It doesn't on DeSmet.
  40.  * If yours does, write something that does tha same thing (its just a simple
  41.  * call to MSDOS), and use it instead of putchar in the kprintf() function.
  42.  */
  43.  
  44. /* "FAST" is the type that produces the fastest local variables. */
  45. /* It is normally "register", but Intel chips are very braindamaged and */
  46. /* don't have enough registers, so you must use "static". */
  47. #define FAST register
  48.  
  49. static int left_flag, do_padding, num1, num2;
  50. static char outbuf[32], *sp_ptr, pad_character;
  51. static int wrow,wcol,wstart,wend;
  52.  
  53. /*
  54.  *    Print on terminal
  55.  */
  56.  
  57. extern int _row1,_row2,_col1,_col2,_attr,g_row,g_col,g_fore,g_back;
  58. #include <ctype.h>
  59. wprintf(ctrl, args)
  60. char *ctrl, *args;
  61. {
  62.     int putachar();
  63.  
  64.     jzgetcur(&wrow,&wcol,&wstart,&wend);
  65.     doprint(putachar, ctrl, &args);
  66. }
  67.  
  68. store_chr(ch)
  69. int ch;
  70. {
  71.     *sp_ptr++ = ch;
  72. }
  73.  
  74. /*
  75.  *    Generalized routine
  76.  */
  77.  
  78. static doprint(outfunc, ctrl, argp)
  79. int (*outfunc)();
  80. char *ctrl, *argp;
  81. {
  82.     FAST int long_flag;
  83.     FAST char *cp, ch;
  84.     FAST int dot_flag;
  85.  
  86.     for (;*ctrl;ctrl++) {
  87.         if (*ctrl!='%') {
  88.             (*outfunc)(*ctrl);
  89.             continue;
  90.         }
  91.         dot_flag=long_flag=left_flag=do_padding=0;
  92.         num2=32767;
  93.         pad_character=' ';
  94.  
  95. try_next:    ch = *(++ctrl);
  96.  
  97.         if (isdigit(ch)) {
  98.             if (dot_flag)
  99.                 num2=getnum(&ctrl);
  100.             else {
  101.                 if (ch=='0')
  102.                     pad_character='0';
  103.                 num1=getnum(&ctrl);
  104.                 do_padding=1;
  105.             }
  106.             ctrl--;
  107.             goto try_next;
  108.         }
  109.  
  110.         switch (tolower(ch)) {
  111.         case 0:
  112.             return;
  113.         case '%':
  114.             (*outfunc)('%');
  115.             continue;
  116.         case '-':
  117.             left_flag=1;
  118.             break;
  119.         case '.':
  120.             dot_flag=1;
  121.             break;
  122.         case 'l':
  123.             long_flag=1;
  124.             break;
  125.         case 'd':
  126.             if (long_flag || ch=='D') {
  127.                 outnum(outfunc, *((long *)argp), 10L);
  128.                 argp+=sizeof(long);
  129.                 continue;
  130.             } else {
  131.                 outnum(outfunc, (long)(*((int *)argp)), 10L);
  132.                 argp+=sizeof(int);
  133.                 continue;
  134.             }
  135.         case 'x':
  136.             if (long_flag || ch=='X') {
  137.                 outnum(outfunc, *((long *)argp), 16L);
  138.                 argp+=sizeof(long);
  139.                 continue;
  140.             } else {
  141.                 outnum(outfunc, (long)(*((int *)argp)), 16L);
  142.                 argp+=sizeof(int);
  143.                 continue;
  144.             }
  145.         case 'o':
  146.             if (long_flag || ch=='X') {
  147.                 outnum(outfunc, *((long *)argp), 8L);
  148.                 argp+=sizeof(long);
  149.                 continue;
  150.             } else {
  151.                 outnum(outfunc, (long)(*((int *)argp)), 8L);
  152.                 argp+=sizeof(int);
  153.                 continue;
  154.             }
  155.         case 's':
  156.             outs(outfunc, *((char **)argp));
  157.             argp+=sizeof(char *);
  158.             continue;
  159.         case 'c':
  160.             (*outfunc)(*((int *)argp));
  161.             argp+=sizeof(int);
  162.             continue;
  163.         case 'f':
  164.         case 'e':
  165.         case 'g':
  166.             do_padding=0;
  167.             num2=32767;
  168.             outs(outfunc, "*No floating point in kprintf!*");
  169.             continue;
  170.         default:
  171.             continue;
  172.         }
  173.         goto try_next;
  174.     }
  175. }
  176.  
  177. /*
  178.  *    Function used to output a line
  179.  */
  180.  
  181. static outs(outfunc, lp)
  182. int (*outfunc)();
  183. char *lp;
  184. {
  185.     FAST int i, len;
  186.  
  187.     /* Blank pad on left if needed */
  188.     if (do_padding && !left_flag && (len=strlen(lp))<num1)
  189.         for (i=len; i<num1; i++)
  190.             (*outfunc)(pad_character);
  191.  
  192.     /* Now output string */
  193.     while (*lp && num2--)
  194.         (*outfunc)(*lp++);
  195.  
  196.     /* Blank pad on right if needed */
  197.     if (do_padding && left_flag && (len=strlen(lp))<num1)
  198.         for (i=len; i<num1; i++)
  199.             (*outfunc)(pad_character);
  200. }
  201.  
  202. /*
  203.  *    Output a number
  204.  */
  205.  
  206. static outnum(outfunc, num, base)
  207. int (*outfunc)();
  208. long num, base;
  209. {
  210.     FAST char *cp;
  211.     FAST int i, len, negative;
  212.     static char digits[]="0123456789ABCDEF";
  213.  
  214.     /* Build number (backwards) in outbuf */
  215.     if (num<0L) {
  216.         negative = 1;
  217.         num = -num;
  218.     } else
  219.         negative = 0;
  220.  
  221.     cp=outbuf;
  222.     do {
  223.         *cp++ = digits[num%base];
  224.     } while ((num/=base) > 0);
  225.     if (negative)
  226.         *cp++ = '-';
  227.     *cp-- = 0;
  228.     len=strlen(outbuf);
  229.  
  230.     /* Blank pad on left if needed */
  231.     if (do_padding && !left_flag && len<num1)
  232.         for (i=len; i<num1; i++)
  233.             (*outfunc)(pad_character);
  234.  
  235.     /* Now output the buffer in reverse order */
  236.     while (cp>=outbuf)
  237.         (*outfunc)(*cp--);
  238.  
  239.     /* Blank pad on right if needed */
  240.     if (do_padding && left_flag && len<num1)
  241.         for (i=len; i<num1; i++)
  242.             (*outfunc)(pad_character);
  243. }
  244.  
  245. /*
  246.  *    Get a number from the control string.
  247.  *
  248.  *    This function takes a pointer to a character pointer (which it
  249.  *    updates to point to the character after the end of the number)
  250.  *    and returns an integer result.
  251.  */
  252.  
  253. static getnum(linep)
  254. char **linep;
  255. {
  256.     FAST int n;
  257.     FAST char *cp;
  258.  
  259.     cp = *linep;
  260.     n = 0;
  261.  
  262.     while (isdigit(*cp))
  263.         n = n*10 + ((*cp++)-'0');
  264.  
  265.     *linep = cp;
  266.     return(n);
  267. }
  268.  
  269. static putachar(fch)
  270. char fch;
  271. {
  272.  
  273.   if (wcol > _col2) {
  274.     wcol = _col1;
  275.     if (wrow == _row2)
  276.       jzscrlup(_row1 << 8 | _col1,_row2 << 8 | _col2,1,_attr);
  277.     else
  278.       ++ wrow;
  279.   }
  280.  
  281.   if (fch) {
  282.     jzwrtchr(fch,_attr,1);
  283.     ++ wcol;
  284.   }
  285.  
  286.   g_row=wrow;
  287.   g_col=wcol;
  288.  
  289.   jzloccur(wrow,wcol);
  290. }
  291.